package com.yuntian.baidu;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yuntian.baidu.conf.CusConfig;
import com.yuntian.baidu.vo.Department;
import com.yuntian.entity.OdsOaOrgUnitLink;
import com.yuntian.entity.OdsOaOrgUnitLinkHis;
import com.yuntian.mapper.OdsOaOrgUnitLinkHisMapper;
import com.yuntian.mapper.OdsOaOrgUnitLinkMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Component
@RequiredArgsConstructor
public class DeptService extends ServiceImpl<OdsOaOrgUnitLinkMapper, OdsOaOrgUnitLink> {

    private List<Department> departmentList;
    private final CusConfig cusConfig;
    private final OdsOaOrgUnitLinkHisMapper odsOaOrgUnitLinkHisMapper;
    private final OdsOaOrgUnitLinkMapper odsOaOrgUnitLinkMapper;
    private final YthService ythService;


    public void syncDept() {
        log.info("清除部门表数据。");
        odsOaOrgUnitLinkMapper.delete(new LambdaQueryWrapper<>());
        List<YthService.OrgData> allOrgData = ythService.getAllOrgData();
        List<OdsOaOrgUnitLink> list = allOrgData.stream().map(v -> {
            var org = new OdsOaOrgUnitLink();
            org.setId(v.getId());
            org.setName(v.getName());
            org.setTypes(v.getType());
            org.setParentId(v.getParent_id());
            org.setPathList(v.getPath_list());
            return org;
        }).collect(Collectors.toList());
        ListUtil.split(list, 500).forEach(v -> {
            this.saveOrUpdateBatch(v);
        });

        List<OdsOaOrgUnitLink> odsOaOrgUnitLinkList = CollUtil.newArrayList();
        int pageNum = 1;
        while (true) {
            // 从数据库读取全量组织数据。
            Page<OdsOaOrgUnitLink> page = this.page(new Page<>(pageNum, 1000), new LambdaQueryWrapper<OdsOaOrgUnitLink>());
            List<OdsOaOrgUnitLink> records = page.getRecords();
            odsOaOrgUnitLinkList.addAll(records);
            if (CollUtil.isEmpty(records)) {
                break;
            }
            pageNum++;
        }
        log.info("odsOaOrgUnitLinkList size:{}", odsOaOrgUnitLinkList.size());
        Map<Integer, List<OdsOaOrgUnitLink>> levelMap = this.convertToLevelMap(odsOaOrgUnitLinkList);
        log.info("integerListMap size:{}", levelMap.size());
        /*List<Tree<String>> trees = this.convertToTree(odsOaOrgUnitLinkList);
        log.info("trees size:{}", trees.size());*/
        // 转换为层级Map
        levelMap.forEach((k, v) -> {
            log.info("层级{}: {}", k, v);
            if (k == 1) {
                log.info("第一层在ab已经存在，跳过。");
            } else if (k == 2) {
                v.forEach(dept -> {
                    // 比对历史表、
                    OdsOaOrgUnitLinkHis odsOaOrgUnitLinkHis = odsOaOrgUnitLinkHisMapper.selectOne(new LambdaQueryWrapper<OdsOaOrgUnitLinkHis>().eq(OdsOaOrgUnitLinkHis::getId, dept.getId()));
                    if (ObjUtil.isEmpty(odsOaOrgUnitLinkHis)) {// 不存在
                        HashMap<String, String> map = MapUtil.newHashMap();
                        map.put("id", dept.getId());
                        map.put("name", dept.getName());
                        map.put("description", "同步的部门");
                        map.put("parent_department_id", cusConfig.getAb().getOrgParentId());
                        String abId = this.orgAdd(map);
                        if (StrUtil.isNotEmpty(abId)) {
                            OdsOaOrgUnitLinkHis org = BeanUtil.copyProperties(dept, OdsOaOrgUnitLinkHis.class);
                            org.setAbid(abId);
                            odsOaOrgUnitLinkHisMapper.insert(org);
                        }
                    } else {
                        // 存在
                    }
                });
            } else {//  3层以上。
                v.forEach(dept -> {
                    // 比对历史表、
                    OdsOaOrgUnitLinkHis odsOaOrgUnitLinkHis = odsOaOrgUnitLinkHisMapper.selectOne(new LambdaQueryWrapper<OdsOaOrgUnitLinkHis>().eq(OdsOaOrgUnitLinkHis::getId, dept.getId()));
                    if (ObjUtil.isEmpty(odsOaOrgUnitLinkHis)) {// 不存在
                        // 根据当前节点的parentId 查找他的abid  第三层取第二层
                        String parentId = dept.getParentId();
                        OdsOaOrgUnitLinkHis odsOaOrgUnitLinkHisParent = odsOaOrgUnitLinkHisMapper.selectOne(new LambdaQueryWrapper<OdsOaOrgUnitLinkHis>().eq(OdsOaOrgUnitLinkHis::getId, parentId));
                        if (ObjUtil.isNotEmpty(odsOaOrgUnitLinkHisParent)) {
                            String parentAbId = odsOaOrgUnitLinkHisParent.getAbid();
                            HashMap<String, String> map = MapUtil.newHashMap();
                            map.put("id", dept.getId());
                            map.put("name", dept.getName());
                            map.put("description", "同步的部门");
                            map.put("parent_department_id", parentAbId);
                            String abId = this.orgAdd(map);
                            if (StrUtil.isNotEmpty(abId)) {
                                OdsOaOrgUnitLinkHis org = BeanUtil.copyProperties(dept, OdsOaOrgUnitLinkHis.class);
                                org.setAbid(abId);
                                odsOaOrgUnitLinkHisMapper.insert(org);
                            }
                        } else {
                            log.warn("{}的父节点{}不存在", dept.getId(), parentId);
                        }

                    } else {
                        // 存在
                    }
                });
            }
        });

    }

    /**
     * AB 系统添加组织。
     * @param map
     * @return
     */

    public String orgAdd(Map<String, String> map) {
        HttpResponse response = HttpRequest.post(cusConfig.getAb().getUrl() + cusConfig.getAb().getOrgAddUrl())
                .header("Authorization", "Bearer " + cusConfig.getAb().getToken()) // 标准Authorization头
                .header("X-Authorization", "Bearer " + cusConfig.getAb().getToken())    // 自定义X-Authorization头
                .header(Header.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)     // 内容类型
                .body(JSONUtil.toJsonStr(map))
                .timeout(20000).execute();
        if (response.isOk()) {
            String body = response.body();
            JSONObject jsonObject = JSONUtil.parseObj(body);
            JSONObject result = jsonObject.getJSONObject("result");
            Integer code = jsonObject.getInt("code");
            if (code == 200) {
                log.info("添加部门成功返回{}", JSONUtil.toJsonStr(result));
                return result.getStr("department_id");
            } else {
                log.error("添加部门失败或者已存在，返回结果：{}", JSONUtil.toJsonStr(jsonObject));
                return "";
            }

        } else {
            log.error("请求失败！状态码：" + response.getStatus());
            return StrUtil.EMPTY;
        }
    }

    /**
     * 将组织列表转换为按层级分组的Map（从指定根节点开始）
     *
     * @param orgList    原始组织列表
     * @param rootNodeId 指定的根节点ID
     * @return 层级Map，key为层级数(从0开始)，value为该层级的所有组织
     */
    public static Map<Integer, List<OdsOaOrgUnitLink>> convertToLevelMap(List<OdsOaOrgUnitLink> orgList, String rootNodeId) {
        if (orgList == null || orgList.isEmpty()) {
            return Collections.emptyMap();
        }
        if (rootNodeId == null || rootNodeId.trim().isEmpty()) {
            throw new IllegalArgumentException("根节点ID不能为空");
        }

        // 1. 构建ID到组织对象的映射，方便快速查找
        Map<String, OdsOaOrgUnitLink> orgMap = orgList.stream()
                .collect(Collectors.toMap(
                        OdsOaOrgUnitLink::getId,
                        org -> org,
                        (existing, replacement) -> existing // 处理ID重复的情况，保留第一个
                ));

        // 2. 验证并获取指定的根节点
        OdsOaOrgUnitLink rootNode = orgMap.get(rootNodeId);
        if (rootNode == null) {
            throw new IllegalArgumentException("指定的根节点不存在: " + rootNodeId);
        }

        // 3. 构建层级Map并递归填充各层级节点（使用LinkedHashMap保持插入顺序）
        Map<Integer, List<OdsOaOrgUnitLink>> levelMap = new LinkedHashMap<>();
        // 根节点层级为0
        fillLevelMap(Collections.singletonList(rootNode), 1, orgMap, levelMap);

        return levelMap;
    }

    /**
     * 递归填充层级Map
     *
     * @param currentNodes 当前节点列表
     * @param currentLevel 当前层级
     * @param orgMap       所有组织的ID映射
     * @param levelMap     要填充的层级Map
     */
    private static void fillLevelMap(List<OdsOaOrgUnitLink> currentNodes, int currentLevel,
                                     Map<String, OdsOaOrgUnitLink> orgMap,
                                     Map<Integer, List<OdsOaOrgUnitLink>> levelMap) {
        if (currentNodes.isEmpty()) {
            return;
        }

        // 将当前层级的节点加入Map
        levelMap.put(currentLevel, new ArrayList<>(currentNodes));

        // 收集当前所有节点的ID作为父ID，批量查找子节点
        Set<String> parentIds = currentNodes.stream()
                .map(OdsOaOrgUnitLink::getId)
                .collect(Collectors.toSet());

        // 一次性找到所有属于下一层级的子节点
        List<OdsOaOrgUnitLink> nextLevelNodes = orgMap.values().stream()
                .filter(org -> org.getParentId() != null && parentIds.contains(org.getParentId()))
                .collect(Collectors.toList());

        // 递归处理下一层级
        fillLevelMap(nextLevelNodes, currentLevel + 1, orgMap, levelMap);
    }

    /**
     * 便捷方法：使用默认根节点ID (-1730833917365171641)
     */
    public static Map<Integer, List<OdsOaOrgUnitLink>> convertToLevelMap(List<OdsOaOrgUnitLink> orgList) {
        // 调用带根节点参数的方法，传入默认根节点ID
        return convertToLevelMap(orgList, "-1730833917365171641");
    }


    /**
     * 使用Hutool将组织列表转换为树形结构
     *
     * @param orgList 原始组织列表
     * @return 树形结构列表（顶层为根节点）
     */
    public static List<Tree<String>> convertToTree(List<OdsOaOrgUnitLink> orgList) {
        if (CollUtil.isEmpty(orgList)) {
            return new ArrayList<>();
        }
        // 1. 转换为Hutool需要的TreeNode列表
        List<TreeNode<String>> treeNodes = orgList.stream().map(org -> {
            TreeNode<String> node = new TreeNode<>();
            // 设置节点ID（必须）
            node.setId(org.getId());
            // 设置父节点ID（必须）
            node.setParentId(org.getParentId());
            // 设置节点名称（可选，用于显示）
            node.setName(org.getName());
            // 扩展字段：将其他属性放入extra
            node.setExtra(Map.of("types", org.getTypes(), "pathList", org.getPathList(), "abid", org.getAbid()));
            return node;
        }).collect(java.util.stream.Collectors.toList());

        // 2. 使用TreeUtil构建树形结构（根节点ID为指定的rootNodeId）
        return TreeUtil.build(treeNodes, "-1");
    }
}
